#pragma once

#include <common.h>
#include <ir/ir.h>
#include <ir/reg.h>
#include <ir/array_info.h>
#include <ir/global_reg.h>

namespace ir {

  /**
   * enum        value
   * NONE       -------
   * FUNCTION   func
   * REG        reg
   * INT        int_number
   * INT_ARRAY  int_array
   * GLOBAL     global_reg
   * */
  class IdenStackResult {
  public:
    enum { NONE, FUNCTION, REG, INT, INT_ARRAY, GLOBAL_REG } tag;
    union {
      Func * func;
      Reg * reg;
      int int_number;
      struct {
        Reg * reg;
        ArrayInfo * array_info;
      } int_array;
      GlobalReg * global_reg;
    };
  };

  class IdenStack {
  public:
    void new_stack();
    void delete_last_stack();
    void push(std::string iden, Reg * reg);
    void push(std::string iden, int int_number);
    void push(std::string iden, Reg * reg, ArrayInfo * array_info);
    void push(std::string iden, GlobalReg * global_reg);
    void push(std::string iden, Func * func);
    IdenStackResult get(std::string iden);

  private:
    using IdenResult = std::map<std::string, IdenStackResult>;
    std::vector<IdenResult> iden_result_list;
  };
}
